import re
import errno

from subprocess import Popen, PIPE


__version__ = '0.1.4'
__locs__ = [12, 47, 358, 8057]


_outlookDummy = {' ': '%20', ',': '%2C', '.': '%2E', '?': '%3F', '!': '%21', ';': '%3B', ':': '%3A'}

_iconMapper = {'Message': 0, 'Warning': 1, 'Error': 2}
_messageImageList = ['message_info', 'message_warning', 'message_error']
_messageColumnNames = ['Time        ', 'Namespace Diff Tool Messages']

_knownPackages = ['agw', 'apptools', 'blockcanvas', 'chaco', 'cloud', 'codetools', 'comtypes', 'coverage',
                  'crypto', 'cython', 'dateutil', 'docutils', 'fwrap', 'html5lib', 'ipython',
                  'jinja', 'lxml', 'matplotlib', 'mayavi', 'networkx', 'numpy', 'opengl',
                  'openssl', 'paramiko', 'psyco', 'pygments', 'pyside', 'pythonwin', 'pytz',
                  'reportlab', 'rst2pdf', 'scipy', 'setuptools', 'sympy', 'sphinx', 'sqlalchemy',
                  'traits', 'tvtk', 'twisted', 'vtk', 'win32com', 'wx', 'wxglade', 'xlrd', 'xlwt',
                  'zope']

_excludedAttrs = ['__builtins__', '__doc__', '__name__', '__file__', '__path__',
                  '__module__', '__all__']

_globalIcons = ['library',
                'package',
                'py_module', 'pyd_module', 'pyc_module', 'pyw_module',
                'klass',
                'method', 'function', 'static_method', 'class_method', 'instance_method',
                'method_descriptor', 'builtin_method', 'builtin_function',
                'property',
                'booltype', 'classtype', 'complextype', 'dictproxytype', 'dicttype', 'filetype',
                'floattype', 'instancetype', 'inttype', 'lambdatype', 'listtype', 'longtype',
                'nonetype', 'objecttype', 'slicetype', 'strtype', 'tracebacktype', 'tupletype',
                'typetype', 'unicodetype', 'unknowntype', 'xrangetype']

_leftIcons = ["nodocs", "one", "two"]

_pklFile = "__ndt_scan__.pkl"

STATIC  = 0
EXPANDO = 1

_panelColumns = {'Attribute': [(u"Object", STATIC), (u"Name", STATIC), (u"Parent", STATIC), (u"Kind", STATIC), (u"Value (repr)", EXPANDO)],
                 'Property':  [(u"Object", STATIC), (u"Name", STATIC), (u"Parent", STATIC), (u"Kind", STATIC), (u"Getter (fget)", EXPANDO), (u"Setter (fset)", EXPANDO), (u"Deleter (fdel)", EXPANDO)],
                 'Method':    [(u"Object", STATIC), (u"Name", STATIC), (u"Parent", STATIC), (u"Kind", STATIC), (u"First line", EXPANDO), (u"Number of Lines", EXPANDO)],
                 'Class':     [(u"Object", STATIC), (u"Name", STATIC), (u"Parent", STATIC), (u"Kind", STATIC), (u"Number of Lines", EXPANDO), (u"Methods", EXPANDO), (u"Properties", EXPANDO), (u"Attributes", EXPANDO)],
                 'Py_Module': [(u"Object", STATIC), (u"Name", STATIC), (u"Parent", STATIC), (u"Kind", STATIC), (u"Filename", EXPANDO), (u"Modules", STATIC), (u"Classes", STATIC), (u"Methods", STATIC), (u"Properties", STATIC), (u"Attributes", STATIC)],
                 'Library':   [(u"Object", STATIC), (u"Name", STATIC), (u"Parent", STATIC), (u"Kind", STATIC), (u"Filename", EXPANDO), (u"Modules", STATIC), (u"Classes", STATIC), (u"Methods", STATIC), (u"Properties", STATIC), (u"Attributes", STATIC)]}

_panelColumns['Package'] = _panelColumns["Py_Module"]
_panelColumns['Pyc_Module'] = _panelColumns["Py_Module"]
_panelColumns['Pyd_Module'] = _panelColumns["Py_Module"]
_panelColumns['Pyw_Module'] = _panelColumns["Py_Module"]


class Enumeration(object):

    def __init__(self, name, enumList):

        self.__doc__ = name
        lookup = { }
        reverseLookup = { }
        i = 0
        uniqueNames = [ ]
        uniqueValues = [ ]

        for item in enumList:
            x = item.upper()
            uniqueNames.append(x)
            uniqueValues.append(i)
            lookup[x] = i
            reverseLookup[i] = x
            i = i + 1

        self.lookup = lookup
        self.reverseLookup = reverseLookup

    def __getattr__(self, attr):

        if not self.lookup.has_key(attr):
            raise AttributeError

        return self.lookup[attr]

    def whatis(self, value):

        return self.reverseLookup[value]


global GLOBAL_ID
GLOBAL_ID = 0

def NewId():
    
    global GLOBAL_ID
    GLOBAL_ID += 1
    return GLOBAL_ID

        
object_types = Enumeration('Object_Types', _globalIcons)

_moduleToIcon = [(".py",  object_types.PY_MODULE, "Py_Module"),   (".pyd", object_types.PYD_MODULE, "Pyd_Module"),
                 (".pyc", object_types.PYC_MODULE, "Pyc_Module"), (".pyw", object_types.PYW_MODULE, "Pyw_Module"),
                 (".so",  object_types.PYD_MODULE, "Pyd_Module")]


SCAN, LOAD, COMPARE = range(3)

_numDiffs = range(11)
NO_DIFF, KIND_DIFF, SIGNATURE_DIFF, CLASSTREE_DIFF, GETSET_DIFF, VALUE_DIFF, ONE_ONLY, TWO_ONLY, LOC_DIFF, FIRSTLINE_DIFF, DOCS_DIFF = _numDiffs

_treeActions = {NO_DIFF:        ('', '', "No difference"),
                KIND_DIFF:      ('SetItemBackgroundColour(subitem, %s)', 'wx.GREEN', 'Item type is different'), 
                SIGNATURE_DIFF: ('SetItemTextColour(subitem, %s)', 'wx.BLUE', 'Signature difference'),
                CLASSTREE_DIFF: ('SetItemTextColour(subitem, %s)', 'wx.RED', 'Class tree difference'),
                GETSET_DIFF:    ('SetItemBackgroundColour(subitem, %s)', 'wx.NamedColour("yellow")', 'Get/Set difference'),
                VALUE_DIFF:     ('SetItemTextColour(subitem, %s)', 'wx.NamedColour("magenta")', 'Value difference'),
                ONE_ONLY:       ('SetItemBackgroundColour(subitem, %s)', 'wx.Colour(255, 193, 37)', 'Item exists only in library 1 (base)'),
                TWO_ONLY:       ('SetItemBackgroundColour(subitem, %s)', 'wx.Colour(255, 69, 0)', 'Item exists only in library 2'),
                LOC_DIFF:       ('SetItemTextColour(subitem, %s)', 'wx.NamedColour("cyan")', 'Number of LOC is different'),
                FIRSTLINE_DIFF: ('SetItemTextColour(subitem, %s)', 'wx.Colour(125, 38, 205)', 'First line of code is different'),
                DOCS_DIFF:      ('SetItemBackgroundColour(subitem, %s)', 'wx.Colour(150, 150, 150)', 'Docstrings are different')
                }

_defaultIgnoreList = [VALUE_DIFF, LOC_DIFF, FIRSTLINE_DIFF, DOCS_DIFF]


ID_FirstPerspective = 10000
ID_Modern = ID_FirstPerspective + 100
ID_Classic = ID_Modern + 1
ID_Top = ID_Modern + 2
ID_Bottom = ID_Modern + 3
ID_NB_Default = ID_Modern + 4
ID_NB_FF2 = ID_Modern + 5
ID_NB_VC71 = ID_Modern + 6
ID_NB_VC8 = ID_Modern + 7
ID_NB_Chrome = ID_Modern + 8
ID_InputPane = ID_Modern + 9
ID_MessageWindow = ID_Modern + 10
ID_DBTree = ID_Modern + 11
ID_ShowInherited = ID_Modern + 12
ID_GreyInherited = ID_Modern + 13
ID_HighlightDocs = ID_Modern + 14
ID_ShowLegend = ID_Modern + 15
ID_TreeTips = ID_Modern + 16
ID_IgnoreList = ID_Modern + 17

ID_CloseTab = ID_Modern + 18
ID_CloseAllTabs = ID_Modern + 19
ID_CloseAllSubTabs = ID_Modern + 20

_popupMenuItems = [("closetab", ID_CloseTab, "Close tab"),
                   ("closealltabs", ID_CloseAllTabs, "Close all tabs"),
                   ("closeallsubtabs", ID_CloseAllSubTabs, "Close all sub-tabs")]

_actionIds = range(11000, 11010)

##CONSTANT_RE = re.compile('^(\w+)[ \t]*=', re.M)
CONSTANT_RE = re.compile('^([\w\s,]+)=', re.M)


ENOENT = getattr(errno, 'ENOENT', 0)
EPIPE  = getattr(errno, 'EPIPE', 0)

_hasDOT = True

try:
    
    p = Popen(['dot', '-h'], stdout=PIPE, stdin=PIPE, stderr=PIPE)

except OSError, err:

    _hasDOT = False
